﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Caching;
using blackhouse.AsyncMail.Business;
using blackhouse.AsyncMail.Business.Data;
using System.Configuration;
using System.Net;
using System.IO;
using System.Net.Mail;

namespace blackhouse.AsyncMail.Web {
    public class CacheTaskRunner {

        #region Fields

        private const string CACHE_KEY = "ASyncMail";

        #endregion

        #region Methods

        public static void RunTaskerOnCache() {
            object asyncmail = HttpContext.Current.Cache[CACHE_KEY];
            if (asyncmail == null) {
                AddCache(HttpContext.Current.Request.Url.GetLeftPart(UriPartial.Authority));
            }
        }

        public static void RerunTaskerOnCache(string key, object value, CacheItemRemovedReason reason) {
            RunTask(value.ToString());
            AddCache(value.ToString());
        }

        private static void RunTask(string host) {
            ASyncMail mail = new ASyncMail(new SqlASyncMailDataAccess(GetConnectionString()));
            while (mail.FillByTop()) {
                try {
                    SendMail(mail, host);
                    mail.MarkAsSended();
                }
                catch (Exception e) {
                    mail.MarkSendError(e.Message + "\r\n" + e.StackTrace);
                }
            }
        }

        private static void SendMail(ASyncMail mail, string host) {
            string url = host + "/" + ASyncHtmlMailGenerator.GetMailDirectory() + "/ASyncHtmlMailGenerator.aspx?requestId=" + mail.RequestId;
            WebRequest request = HttpWebRequest.Create(url);
            WebResponse response = request.GetResponse();
            string mailToSend = "";
            using (Stream stream = response.GetResponseStream())
            using (StreamReader sr = new StreamReader(stream)) {
                mailToSend = sr.ReadToEnd();
            }
            MailMessage mailMessage = new MailMessage();
            SmtpClient client = new SmtpClient();
            if (client.Port == 587)
                client.EnableSsl = true;
            mailMessage.Subject = mail.MessageTitle;
            mailMessage.Body = mailToSend;
            mailMessage.IsBodyHtml = true;
            mailMessage.To.Add(mail.Receiver);
            client.Send(mailMessage);
        }

        private static void AddCache(string value) {
            HttpContext.Current.Cache.Add(CACHE_KEY,
                value,
                null,
                DateTime.Now + TimeSpan.FromSeconds(GetCacheInterval()),
            System.Web.Caching.Cache.NoSlidingExpiration,
            System.Web.Caching.CacheItemPriority.AboveNormal,
            new System.Web.Caching.CacheItemRemovedCallback(RerunTaskerOnCache));
        }

        internal static string GetAppHost() {
            object path = HttpContext.Current.Cache[CACHE_KEY];
            if (path == null)
                return "";
            else
                return path.ToString();
        }

        internal static string GetConnectionString() {
            return ConfigurationManager.AppSettings["MSSQLConnectionString"];
        }

        private static int GetCacheInterval() {
            string sInt = ConfigurationManager.AppSettings["CacheInterval"];
            if (!string.IsNullOrEmpty(sInt)) {
                int iInt = 0;
                if (Int32.TryParse(sInt, out iInt))
                    return iInt;
            }
            return 30;
        }

        #endregion

    }
}